﻿/**
 @author Eric AMBROSI
 @alias ricko || rickota || ricota
 @classDescription allow to tween object in Silverlight 2
 @version 2.1.2 stable version
*/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Tweened
{


    #region TweenableProperties :: les propriétés qu'on peut affecter
     
    /// <summary>
    ///     This class contains the static definition of all properties Tweenable for setting TweenObject constructor.
    ///     if you want to know what you can do, just check properties members
    /// </summary>
    public static class TweenableProperties
    {
        //simple Properties
        /// <summary>
        /// Applies a Tween on the property Canvas.Left an object in pixels, this value is relative to the origin of the canvas container.
        /// </summary>
        public static TweenedProperty Left = new TweenedProperty(TweenedType.Simple, "(Canvas.Left)", Canvas.LeftProperty, PropertyType.SimpleType, "Double");
        /// <summary>
        /// Applies a Tween on the property Canvas.Top an object in pixels, this value is relative to the origin of the canvas container.
        /// </summary>
        public static TweenedProperty Top = new TweenedProperty(TweenedType.Simple, "(Canvas.Top)", Canvas.TopProperty, PropertyType.SimpleType, "Double");
        
        /// <summary>
        /// Applies a Tween on the property Width of an object in pixels.
        /// </summary>
        public static TweenedProperty Width = new TweenedProperty(TweenedType.Simple, "Width", Canvas.WidthProperty, PropertyType.SimpleType, "Double");
        /// <summary>
        /// Applies a Tween on the property Height of an object in pixels.
        /// </summary>
        public static TweenedProperty Height = new TweenedProperty(TweenedType.Simple, "Height", Canvas.HeightProperty, PropertyType.SimpleType, "Double");
        /// <summary>
        /// Applies a Tween on the opacity of an object, values must be between 0 and 1.
        /// </summary>
        public static TweenedProperty Opacity = new TweenedProperty(TweenedType.Simple, "Opacity", UIElement.OpacityProperty, PropertyType.SimpleType, "Double");
        
        //RenderTransform Properties(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)
        
        /// <summary>
        /// 	Applies a Tween on the property X of an object in pixels,this value is relative to its original position regardless of the container.
        /// </summary>
        public static TweenedProperty X = new TweenedProperty(TweenedType.RenderTransform, @"(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)", TranslateTransform.XProperty, PropertyType.TranslateType, "Double");
        
        /// <summary>
        /// 	Applies a Tween on the property Y of an object in pixels,this value is relative to its original position regardless of the container.
        /// </summary>
        public static TweenedProperty Y = new TweenedProperty(TweenedType.RenderTransform, @"(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)", TranslateTransform.YProperty, PropertyType.TranslateType, "Double");
        
        /// <summary>
        /// 	Applies a Tween on the property ScaleX of an object in percent, values must be between 0 and 1.
        /// </summary>
        public static TweenedProperty ScaleX = new TweenedProperty(TweenedType.RenderTransform, @"(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)", ScaleTransform.ScaleXProperty, PropertyType.ScaleType, "Double");
        
        /// <summary>
        /// 	Applies a Tween on the property ScaleY of an object in percent, values must be between 0 and 1.
        /// </summary>
        public static TweenedProperty ScaleY = new TweenedProperty(TweenedType.RenderTransform, @"(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)", ScaleTransform.ScaleYProperty, PropertyType.ScaleType, "Double");
        
        /// <summary>
        /// 	Applies a Tween on the property AngleX of an object in degre.
        /// </summary>
        public static TweenedProperty AngleX = new TweenedProperty(TweenedType.RenderTransform, @"(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)", SkewTransform.AngleXProperty, PropertyType.SkewType, "Double");
        
        /// <summary>
        /// 	Applies a Tween on the property AngleX of an object in degree.
        /// </summary>
        public static TweenedProperty AngleY = new TweenedProperty(TweenedType.RenderTransform, @"(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleY)", SkewTransform.AngleYProperty, PropertyType.SkewType, "Double");
        
        /// <summary>
        /// 	Applies a Tween on the property AngleY of an object in degree.
        /// </summary>
        public static TweenedProperty Angle = new TweenedProperty(TweenedType.RenderTransform, @"(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)", RotateTransform.AngleProperty, PropertyType.RotateType, "Double");
        
        //propriétés de couleur
        
        /// <summary>
        ///     Applies a Tween on the Fill color of Shapes. example : Color.FromArgb(255, 20, 150, 68)
        /// </summary>
        public static TweenedProperty Fill = new TweenedProperty(TweenedType.Color, @"(UIElement.Fill).(SolidColorBrush.Color)", Shape.FillProperty, PropertyType.ColorType, "Color");
        
        /// <summary>
        ///     Applies a Tween on the Stroke color of Shapes. example of value : Color.FromArgb(255, 20, 150, 68)
        /// </summary>
        public static TweenedProperty Stroke = new TweenedProperty(TweenedType.Color, @"(UIElement.Stroke).(SolidColorBrush.Color)", Shape.StrokeProperty, PropertyType.ColorType, "Color");
        
        /*
        /// <summary>
        ///     Applies a Tween on the Background color of Controls. example of value : Color.FromArgb(255, 20, 150, 68)
        /// </summary>
        public static TweenedProperty Background = new TweenedProperty(TweenedType.Color, @"(UIElement.Background).(SolidColorBrush.Color)", Canvas.BackgroundProperty, PropertyType.ColorType, "Color");

        /// <summary>
        ///     Applies a Tween on the Foreground color of Controls. example of value : Color.FromArgb(255, 20, 150, 68)
        /// </summary>
        public static TweenedProperty Foreground = new TweenedProperty(TweenedType.Color, @"(UIElement.Foreground).(SolidColorBrush.Color)", TextBlock.ForegroundProperty, PropertyType.ColorType, "Color");
        */
    }
    #endregion

    #region types de Tween et de propriété

    /// <summary>
    ///     This list contains all types of properties tweenable. There's no need to use it.
    /// </summary>
    public enum TweenedType
    {
        /// <summary>
        ///     This sort of property is typed double, directly accessible in the tag of UIElement as Canvas.Left for example:
        ///     <code><Rectangle Canvas.Left="50" /></code>
        /// </summary>
        /// <remarks>
        /// For setting this kind of property, you can use SetTweenedProperty() public method of TweenObject class.
        /// </remarks>
        Simple,
 
        /// <summary>
        ///     This sort of property is typed double, not directly accessible in the tag of UIElement as Canvas.Left for example:
        ///     	<code>
        /// <![CDATA[
        /// <Rectangle Height="55" Width="85" Canvas.Left="178" Fill="#FFFF2C2C" x:Name="can" RenderTransformOrigin="0.5,0.5" Canvas.Top="93">
		///     <Rectangle.RenderTransform>
		///         <TransformGroup>
	    ///             <ScaleTransform ScaleX="1" ScaleY="1"/>
		///             <SkewTransform AngleX="0" AngleY="0"/>
		///             <RotateTransform Angle="0"/>
		///             <TranslateTransform X="0" Y="0"/>
		///         </TransformGroup>
		///     </Rectangle.RenderTransform>
        /// </Rectangle>
        /// ]]>
        ///         </code>	
        /// </summary>
        /// <remarks>
        /// For setting this kind of property, you can use SetTweenedProperty() public method of TweenObject class.
        /// </remarks>
        RenderTransform,

        /// <summary>
        ///     This sort of property is typed Color, directly accessible in the tag of UIElement as Fill for example:
        ///     <code><Rectangle Fill="#FF56A9B2" /></code>
        /// </summary>
        /// <remarks>
        /// For setting this kind of property, you can use SetTweenedProperty() public method of TweenObject class.
        /// </remarks>
        Color
    }

    internal static class PropertyType
    {
        internal static TranslateTransform TranslateType = new TranslateTransform();
        internal static RotateTransform RotateType = new RotateTransform();
        internal static ScaleTransform ScaleType = new ScaleTransform();
        internal static SkewTransform SkewType = new SkewTransform();
        internal static SolidColorBrush ColorType = new SolidColorBrush();
        internal static UIElement SimpleType;
    }
    #endregion

    #region PropertieClass

    /// <summary>
    ///     this class contains all that defines a propertie that can be tweened. There's no need to use it.
    /// </summary>
    public class TweenedProperty
    {
        //la propriété à cibler dans le StoryBoard
        internal string Prop { get; set; }
        //la propriété à cibler dans l'objet
        internal DependencyProperty AccessProp { get; set; }
        //le type de propriété Ciblée
        internal DependencyObject PropType { get; set; }
        //le type d'animation
        internal string AnimationType { get; set; }
        //la description de la propriété
        internal TweenedType TType { get; set; }
        //le chemin d'accès
        internal PropertyPath cheminProp { get; set; }//le chemin d'accès des propriétés

        internal TweenedProperty(TweenedType tType, string propertie, DependencyProperty accessPropertie, DependencyObject propType, string animationType)
        {
            this.Prop = propertie;
            this.AccessProp = accessPropertie;
            this.PropType = propType;
            this.AnimationType = animationType;
            this.TType = tType;
            this.cheminProp = new PropertyPath(Prop);
        }
    }

    #endregion
}
